<?php
class configs{
    static $config=array();

    static public function set_config_copy($key,$value){
        if(!is_array($key) && !is_object($key) && !is_bool($key)){
            if(strpos($key,'.')>0 && substr($key,-1) !=='.'){
                $list = explode('.',$key);
                if(count($list)>1){
                    self::set_arr(self::$config,$list,$value);
                }
            }else{
                if($key !="" && $value!=""){
                    self::$config[$key] = $value;
                }
            }
        }else{
            if(is_array($key)){
                foreach ($key as $k => $v) {
                    //self::set_config($k,$v);
                    self::$config[$k] = $v;
                }
            }
        }
    }
    static public function get_config_copy($name){
        if($name == ""){
            return self::$config;
        }
        if(!is_array($name) && !is_object($name) && !is_bool($name)){
            if(strpos($name,'.')>0 && substr($name,-1) !=='.'){
                $list = explode('.',$name);
                if(count($list)>1){
                    self::get_arr(self::$config,$list,$v);
                    return $v;
                }
            }
            if($name !=""){
                return self::$config[$name];
            }
        }
    }
    static public function get_arr(&$conf,&$leval_arr=array(),&$return_value){
        if(count($leval_arr)>0){
            foreach ($leval_arr as $key => $value) {
                unset($leval_arr[$key]);
                self::get_arr($conf[$value],$leval_arr,$return_value);
            }
        }else{
            $return_value = $conf;
        }
    }
    static public function set_arr(&$conf,&$leval_arr=array(),$set_value){
        if(count($leval_arr)>0){
            foreach ($leval_arr as $key => $v) {
                unset($leval_arr[$key]);
                self::set_arr($conf[$v],$leval_arr,$set_value);
            }
        }else{
            $conf = $set_value;
        }
    }

    static public function set_config($key,$value){
        if(is_array($key) && empty($value)){
            foreach ($key as $k => $v) {
                self::$config[$k] = $v;
            }
        }else{
            self::set_array(self::$config,$key,$value);
        }
    }
    static public function get_config($name){
        return self::get_array(self::$config,$name);
    }

    /**
     * 设置数组, 如: set_array($arr,'lv1.lv2',$value); set_array($arr,array('lv1','lv2'),$value);
     * @param $arr
     * @param string $name
     * @param string $value
     * @param int $index
     * @return mixed
     */
    static public function set_array(&$arr,$name='',$value='', $index = 0){
        if($name && is_array($name)){
            $len = count($name);
            if($len > 0 && $index<$len){
                if(!isset($arr[$name[$index]]) || !is_array($arr[$name[$index]])){
                    $arr[$name[$index]] = array();
                    if($index == $len-1){
                        $arr[$name[$index]] = $value;
                        return $arr;
                    }
                }
                self::set_array($arr[$name[$index]],$name,$value,$index+1);
            }
        }elseif ($name && is_string($name) && strpos($name,'.') > 0){
            $name = explode('.',$name);
            self::set_array($arr,$name,$value,$index);
        }else{
            $arr[$name] = $value;
        }
    }

    /**
     * 获取数组 如： get_array($arr,'lv1.lv2'); get_array($arr,array('lv1','lv2'));
     * @param $arr
     * @param $name
     * @param int $index
     * @return mixed
     */
    static public function get_array(&$arr,$name,$index=0)
    {
        if($name && is_array($name)){
            $len = count($name);
            if($len > 0 && $index<$len){
                if($index == $len-1){
                    return $arr[$name[$index]];
                }
                return self::get_array($arr[$name[$index]],$name,(int)$index+1);
            }
        }elseif ($name && is_string($name) && strpos($name,'.') > 0){
            $name = explode('.',$name);
            return self::get_array($arr,$name,$index);
        }else{
            return $name ? $arr[$name] : $arr;
        }
    }

    /**
     * 获取缓存文件信息
     * @param string $name
     * @param string $tag
     * @param string $cache_dir
     * @return bool|array|string
     */
    static public function cache_get($name = '', $tag = 'auto_', $cache_dir = '/cache_files'){
        $tag = empty($tag) ? 'auto_' : $tag;
        $project_dir = rtrim(str_replace('\\','/',PROJECT_DIR),'/');
        $cache_file_dir = preg_replace('/[\\\\\/]{2,}/i', '/', $project_dir . '/' . $cache_dir);
        $cache_file_name = md5($tag . $name) . '.txt';
        $cache_file_path = preg_replace('/[\\\\\/]{2,}/i','/',$cache_file_dir . '/' . $cache_file_name);
        $data = '';
        if (is_file($cache_file_path)) {
            $data = file_get_contents($cache_file_path);
            $data = unserialize($data);
        }
        //文件生成或修改时间
        $mod_time = filemtime($cache_file_path);
        $mod_time = $mod_time ? $mod_time : filectime($cache_file_path);

        if($data['expire'] > 0 ){
            $_t = $mod_time + $data['expire'];
            if($_t >= time()){
                return $data['data'];
            }else{
                //过期时间到后就删除文件
                $del_ok = @unlink($cache_file_path);
                return false;
            }
        }
        return $data['data'];
    }

    /**
     * 设置文件缓存
     * @param string $name  名称
     * @param string $value  存入内容
     * @param string $tag  标记
     * @param int $expire  过期时间【小于等于0的时候为永久缓存】
     * @param string $cache_dir  文件缓存目录
     * @return bool|int
     */
    static public function cache_set($name = '', $value = '', $tag = 'auto_', $expire = 0, $cache_dir = '/cache_files'){
        $tag = empty($tag) ? 'auto_' : $tag;
        $project_dir = rtrim(str_replace('\\','/',PROJECT_DIR),'/');
        $cache_file_dir = preg_replace('/[\\\\\/]{2,}/i', '/', $project_dir . '/' . $cache_dir);
        $cache_file_name = md5($tag . $name) . '.txt';
        $cache_file_path = preg_replace('/[\\\\\/]{2,}/i','/',$cache_file_dir . '/' . $cache_file_name);

        if(!is_dir($cache_file_dir) ){
            $ok = @mkdir($cache_file_dir,0776,true);
        }
        if($name !== '' && !is_array($name) && !is_object($name) && $value != ''){
            //过期时间
            $data['expire'] = $expire;
            $data['data'] = $value;
            $data = serialize($data);
            $bit = file_put_contents($cache_file_path,$data,LOCK_EX);
        }
        return $bit;
    }

    /**
     * 删除文件缓存
     * @param string $name  名称
     * @param string $tag  标记
     * @param string $cache_dir  文件缓存目录
     * @return bool
     */
    static public function cache_del($name = '', $tag = 'auto_', $cache_dir = '/cache_files'){
        if(is_array($name) || is_object($name)){
            foreach ($name as $key => $value) {
                self::cache_del($value,$tag,$cache_dir);
            }
        }else{
            if($name !== '' && !is_bool($name)){
                $tag = empty($tag) ? 'auto_' : $tag;
                $project_dir = rtrim(str_replace('\\','/',PROJECT_DIR),'/');
                $cache_file_dir = preg_replace('/[\\\\\/]{2,}/i', '/', $project_dir . '/' . $cache_dir);
                $cache_file_name = md5($tag . $name) . '.txt';
                $cache_file_path = preg_replace('/[\\\\\/]{2,}/i','/',$cache_file_dir . '/' . $cache_file_name);
                $del_ok = @unlink($cache_file_path);
                return $del_ok;
            }
        }
    }

    static public function session_init($session_key = 'session_data',$t = 0)
    {

        //$Lifetime = 3600;
        //$DirectoryPath = "./tmp";
        //is_dir($DirectoryPath) or mkdir($DirectoryPath, 0777);
        //是否开启基于url传递sessionid,这里是不开启，发现开启也要关闭掉
        //if (ini_get("session.use_trans_sid") == true) {
        //    ini_set("url_rewriter.tags", "");
        //    ini_set("session.use_trans_sid", false);
        //}
        //ini_set("session.gc_maxlifetime", $Lifetime);//设置session生存时间
        //ini_set("session.gc_divisor", "1");
        //ini_set("session.gc_probability", "1");
        //ini_set("session.cookie_lifetime", "0");//sessionID在cookie中的生存时间
        //ini_set("session.save_path", $DirectoryPath);//session文件存储的路径


        $t && session_set_cookie_params($t);#注意到放到start的前面
        session_start();
        $t && setcookie(session_name(),session_id(),time()+$t);
        self::$config['session_key'] = md5($session_key);
        !isset($_COOKIE[session_name()]) && $_SESSION[self::$config['session_key']] = array(
            'session_name' => session_name(),
            'session_id' => session_id(),
            'user_agent' => $_SERVER['HTTP_USER_AGENT'],
        );
    }
    static public function session_set($name = '', $value = '', $prefix = '')
    {
        if (is_array($name) && count($name) > 0 && empty($value)) {
            //$name 为数组(一维关联数组时)批量添加
            foreach ($name as $key => $val) {
                $_SESSION[self::$config['session_key']][$prefix . $key] = $val;
            }
        } else {
            if (!empty($name)) {
                $_SESSION[self::$config['session_key']][$prefix . $name] = $value;
            }
        }
    }
    static public function session_get($name = '', $prefix = '')
    {
        if (!empty($name)) {
            return $_SESSION[self::$config['session_key']][$prefix . $name];
        } else {
            return $_SESSION[self::$config['session_key']];
        }
    }
    static public function session_del($name = '', $prefix = '')
    {
        if (is_array($name) && count($name) > 0) {
            //$name 为一维数组时批量删除
            foreach ($name as $item) {
                unset($_SESSION[self::$config['session_key']][$prefix . $item]);
            }
        } elseif (empty($name) && !empty($prefix) && is_string($prefix)) {
            // 按前缀批量删除
            foreach ($_SESSION[self::$config['session_key']] as $key => $value) {
                if (strpos(trim($key), $prefix) < 1) {
                    unset($_SESSION[self::$config['session_key']][$key]);
                }
            }
        } else {
            if ($name) {
                unset($_SESSION[self::$config['session_key']][$prefix . $name]);
            }
        }
    }
    static public function session_destroy()
    {
        $_SESSION = array();
        if(isset($_COOKIE[session_name()])) {
            setCookie(session_name(), "", time()-42000, "/");
        }
        $session_id = session_id();
        session_destroy();
        return $session_id;
    }

    /**
     * 字符串截取和返回字符串的长度
     * @param string $str 要截取的字符串
     * @param int $start 字符串截取的初始位置，从0开始
     * @param int $length 字符串截取的长度
     * @param string $charset 字符串编码
     * @param bool $suffix 是否添加后缀
     * @param bool $strlen 是否返回字符串的长度(false不返回,true返回)
     * @return int|string
     */
    static public function my_substr($str, $start = 0, $length, $charset = 'utf-8', $suffix = true, $strlen = false)
    {
        $charset || ($charset = 'utf-8');
        //正则表达式匹配编码
        $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
        $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
        $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
        $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
        //返回字符串长度
        if ($strlen) {
            if (function_exists('mb_strlen')) {
                $count = mb_strlen($str, $charset);
            } elseif (function_exists('iconv_strlen')) {
                $count = iconv_strlen($str, $charset);
            } else {
                preg_match_all($re[$charset], $str, $match);
                $count = count($match[0]);
            }
            return $count;
        }
        //截取字符串
        if (function_exists("mb_substr"))
            $slice = mb_substr($str, $start, $length, $charset);
        elseif (function_exists('iconv_substr')) {
            $slice = iconv_substr($str, $start, $length, $charset);
            if (false === $slice) {
                $slice = '';
            }
        } else {
            preg_match_all($re[$charset], $str, $match);
            $slice = join("", array_slice($match[0], $start, $length));
        }
        //字数不满添加后缀 ...
        if ($suffix) {
            $count = self::my_substr($str, $start, $length, $charset, false, true);
            if ($count > $length) {
                return $slice . '......';
            } else {
                return $slice;
            }
        } else {
            return $slice;
        }
    }

    /**
     * 返回字符串长度
     * @param string $str
     * @param string $charset
     * @return int
     */
    static public function my_strlen($str, $charset = 'utf-8')
    {
        $charset || ($charset = 'utf-8');
        //正则表达式匹配编码
        $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
        $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
        $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
        $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";

        //返回字符串长度
        if (function_exists('mb_strlen')) {
            $count = mb_strlen($str, $charset);
        } elseif (function_exists('iconv_strlen')) {
            $count = iconv_strlen($str, $charset);
        } else {
            preg_match_all($re[$charset], $str, $match);
            $count = count($match[0]);
        }
        return $count;
    }

    /**
     * 字符串分隔
     * @param string $str
     * @param int $split_length
     * @param string $charset
     * @return array|array[]|bool|false|string[]
     */
    static public function my_str_split($str, $split_length = 1, $charset = 'utf-8')
    {
        if (func_num_args() == 1 && strtolower($charset) === 'utf-8') {
            return preg_split('/(?<!^)(?!$)/u', $str);
        }
        if ($split_length < 1) {
            return false;
        }
        $len = self::my_strlen($str, $charset);
        $arr = array();
        for ($i = 0; $i < $len; $i += $split_length) {
            $s = self::my_substr($str, $i, $split_length, $charset, false);
            $arr[] = $s;
        }
        return $arr;
    }

    /**
     * 把搜索词分割成多段并存储（存在 $save_arr 参数里面），左->右，字数由多到少，$save_arr 最终是一个二维数组
     * @param int $length 截取的长度
     * @param array $array 一维数组
     * @param $save_arr
     */
    static public function search_search1($length, $array, &$save_arr){
        for ($i = 0, $len = count($array); $i < $len; $i++) {
            ($i + $length <= $len) && ($save_arr[] = array_slice($array, $i, $length));
        }
    }

    /**
     * 搜索词分割
     * @param string $keyword 搜索词
     * @param int|boolean $toStirng [布尔值或者 0，1]
     * @return bool|array
     */
    static public function search_keywords($keyword, $toStirng = 0){
        if(!$keyword){return false;}
        $array = self::my_str_split($keyword);
        $len = count($array);
        for($i = $len;$i>0;$i--){
            self::search_search1($i,$array,$save_arr);
        }
        if($toStirng){
            for($i=0,$len=count($save_arr);$i<$len;$i++){
                $save_arr[$i] = join('',$save_arr[$i]);
            }
        }
        return $save_arr ? $save_arr : false;
    }

    /**
     * 浏览器友好的变量输出
     * @param mixed $var 变量
     * @param boolean $echo 是否输出 默认为True 如果为false 则返回输出字符串
     * @param string $label 标签 默认为空
     * @param boolean $strict 是否严谨 默认为true
     * @return void|string
     */
    static public function dump($var, $echo=true, $label=null, $strict=true){
        $label = ($label === null) ? '' : rtrim($label) . ' ';
        if (!$strict) {
            if (ini_get('html_errors')) {
                $output = print_r($var, true);
                $output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';
            } else {
                $output = $label . print_r($var, true);
            }
        } else {
            ob_start();
            var_dump($var);
            $output = ob_get_clean();
            if (!extension_loaded('xdebug')) {
                $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output);
                $output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';
            }
        }
        if ($echo) {
            echo($output);
            return null;
        }else
            return $output;
    }    

    static public function __callStatic($name, $arguments)
    {
        // TODO: Implement __callStatic() method.
        $className = self::class;
        var_dump("方法 $className::$name(".join(', ',$arguments).") 不可访问或不存在");
    }
}